package com.carlinfo.usercenter.common.util;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

/**
 * 标准的JDBC
 * ~单例模式 一个jvm里只能有一个对象
 * 构造方法私有
 * 提供一个属性,类型是自己,new一个对象
 * 提供一个方法,返回值是自己,修饰符是public static
 * 
 * 封装JDBC
 * 将加载的驱动只执行一次
 * 第二步放到一个方法中
 * 将经常使用的内容放到配置文件中,资源文件,ResourceBundle 
 * 	
 * @author jjh
 *
 */
public class DbUtil
{
	/**
	 * 为了属性的安全:设置值和获取值(set/get)
	 */
	private static DbUtil INSTANCE = new DbUtil() ; 
	
	/* 变量 
	private String driver = "com.mysql.jdbc.Driver";
	 jdbc的url;
	 * http://www.cnblogs.com/iamfy/archive/2012/07/11/2586869.html
	 * 参数是:url; jdbc:mysql://localhost:3306/userscenter_20180108?user=&password=
	 *  
	private String url = "jdbc:mysql://localhost:3306/userscenter_20180108?useSSL=true";
	private String user = "root";
	private String password = "123456";*/
	
	/* 变量 */
	private String driver = ConstatFinalUtil.BUNDLE.getString("jdbc.driver");
	/* jdbc的url;
	 * http://www.cnblogs.com/iamfy/archive/2012/07/11/2586869.html
	 * 参数是:url; jdbc:mysql://localhost:3306/userscenter_20180108?user=&password=
	 *  */
	private String url = ConstatFinalUtil.BUNDLE.getString("jdbc.url");
	private String user = ConstatFinalUtil.BUNDLE.getString("jdbc.user");
	private String password = ConstatFinalUtil.BUNDLE.getString("jdbc.password");
	
	public static void main(String[] args)
	{
		standardJDBC();
	}
	/**
	 * 私有的构造方法 
	 */
	private DbUtil()
	{
		/* 单例模式,此代码只执行一次 */
		try
		{
			Class.forName(driver);
		} catch (ClassNotFoundException e)
		{
			System.out.println("==加载驱动失败==");
			e.printStackTrace();
		}
	}
	
	/** static: 构造方法私有了,外面的类不能new了，如果此方法不被static修饰,那么getInstance,是必须要new的吧,只能被static修饰了 
	 * @return
	 * */
	public static DbUtil getInstance()
	{
		return INSTANCE ;
	}
	/**
	 * 获取一个链接 
	 * @return
	 */
	public Connection getConnection()
	{
		/* 获取链接 */
		Connection connection = null ;
		try
		{
			connection = DriverManager.getConnection(url, user, password);
		} catch (SQLException e)
		{
			System.out.println("==获取链接失败==");
			e.printStackTrace();
		}
		return connection ;
	}
	/**
	 * 关闭链接,关闭语句,关闭rs
	 * @param connection   jdbc的链接
	 * @param st  sql语句对象
	 * @param rs  查询的结果
	 */
	public void colseAll(Connection connection , Statement st , ResultSet rs)
	{
		try
		{
			if(rs != null)
			{
				rs.close();
				rs = null ; 
			}
		} catch (SQLException e)
		{
			e.printStackTrace();
		}
		
		try
		{
			if(st != null)
			{
				st.close();
				st = null ; 
			}
		} catch (SQLException e)
		{
			e.printStackTrace();
		}
		
		try
		{
			if(connection != null)
			{
				connection.close();
				connection = null ; 
			}
		} catch (SQLException e)
		{
			e.printStackTrace();
		}
	}
	
	/**
	 * 封装后的JDBC
	 */
	public static void encapsulationJDBC()
	{
		System.out.println("===封装后的JDBC===");
		String sql = "select * from a_role " ;
		
		PreparedStatement ps = null ;
		ResultSet rs = null ;
		/* 先创建对象,不能new */
		DbUtil dbUtil = DbUtil.getInstance();
		/* 获取链接 */
		Connection connection = dbUtil.getConnection();
		
		try
		{
			ps = connection.prepareStatement(sql);
			rs = ps.executeQuery() ; 
			/* 到底是循环还是选择
			 * 如果查询的结果是多条,就用判断
			 * 如果是单条:就用选择
			 * 
			 * rs == 班长== 迭代器==enumeration(枚举)
			 *  */
			while(rs.next())
			{
				/*
				 * 参数为整数:指的是sql语句执行以后;列的顺序
				 * 参数为字符串时:指的是sql语句执行以后列的别名;
				 * */
				int id = rs.getInt(1);
				String name = rs.getString("name");
				System.out.println("id:" + id + ";name" + name);
			}
		} catch (SQLException e)
		{
			e.printStackTrace();
		}finally
		{
			dbUtil.colseAll(connection, ps, rs);
		}
		
		
	}
	/**
	 * 标准的JDBC代码
	 * 查询角色表中的所有记录
	 */
	private static void standardJDBC()
	{
		/*
		 * Jdbc:四步走:
		加载驱动
		获取链接
		操作数据库
		关闭链接
		
		查询角色表中所有的记录
		 * */
		String driver = "com.mysql.cj.jdbc.Driver";
		/* jdbc的url;
		 * http://www.cnblogs.com/iamfy/archive/2012/07/11/2586869.html
		 * 参数是:url; jdbc:mysql://localhost:3306/userscenter_20180108?user=&password=
		 *  */
		String url = "jdbc:mysql://localhost:3306/usercenter?serverTimezone=GMT%2B8&useSSL=true";
		String user = "root";
		String password = "123456";
		/* 写上sql语句 */
		String sql = "select * from a_role ; " ; 
		
		/* 为对象赋初始值 */
		Connection connection = null ; 
		PreparedStatement ps = null ; 
		ResultSet rs = null ;
		try
		{
			/* 加载驱动 */
			Class.forName(driver);
			/* 获取链接 */
			connection = DriverManager.getConnection(url, user, password);
			/* 操作数据库
			 * 创建一个SQL语句,将SQL语句发送到数据库中
			 * Statement:木有预先加载;
			 * String name = "aa" ;
			 * String pass = "' or 1 = 1 or name = '232323232323" ;//SQL注入 
			 * select * from users where name = '"+ name +"' and password = '" + name + "' ; 
			 * preparedStatement:预先加载
			 * ?:占位符
			 * SQL注入
			 *  */
			ps = connection.prepareStatement(sql);
			rs = ps.executeQuery() ; 
			/* 到底是循环还是选择
			 * 如果查询的结果是多条,就用循环
			 * 如果是单条:就用选择
			 * 
			 * rs == 班长== 迭代器==enumeration(枚举)
			 *  */
			while(rs.next())
			{
				/*
				 * 参数为整数:指的是sql语句执行以后;列的顺序
				 * 参数为字符串时:指的是sql语句执行以后列的别名;
				 * */
				int id = rs.getInt(1);
				String name = rs.getString("name");
				System.out.println("id:" + id + ";name" + name);
			}
		} catch (ClassNotFoundException e)
		{
			System.out.println("==加载驱动失败==");
			e.printStackTrace();
		} catch (SQLException e)
		{
			System.out.println("==获取链接失败==");
			e.printStackTrace();
		}finally
		{
			try
			{
				if(rs != null)
				{
					rs.close();
					rs = null ; 
				}
			} catch (SQLException e)
			{
				e.printStackTrace();
			}
			
			try
			{
				if(ps != null)
				{
					ps.close();
					ps = null ; 
				}
			} catch (SQLException e)
			{
				e.printStackTrace();
			}
			
			try
			{
				if(connection != null)
				{
					connection.close();
					connection = null ; 
				}
			} catch (SQLException e)
			{
				e.printStackTrace();
			}
		}
	}
}
